跳到主要内容

本章将介绍 ROS2 中的动作(Actions)通信机制,通过实际的Python代码示例,演示动作服务器和动作客户端的创建过程及其使用场景。

动作(Action)的基本概念

ROS2 中的动作(Actions)是一种特殊的通信模式,用于需要长时间执行并伴随反馈(feedback)或可能中途取消的任务。与服务(Service)的请求-响应模式不同,动作提供了目标(Goal)、反馈(Feedback)和结果(Result)三个组成部分。

动作适用于以下场景:

  • 导航到特定位置
  • 执行抓取物体任务
  • 执行复杂计算任务并提供进度反馈

动作通信流程

图 1 中展示了 ROS2 中动作通信机制的详细交互过程,通过节点(Node)之间的通信来实现长时间运行的任务,具体流程如下:

ROS2 不同节点下服务通信方式的服务端和客户端使用流程

图 1: ROS2 动作流程

主要组件说明:

ROS2 的动作通信模型主要由动作客户端(Action Client)和动作服务器(Action Server)组成:

  • 动作客户端(Action Client)

    • 目标客户端(Goal Service Client):发送目标请求(Goal Request)到服务器。

    • 反馈订阅者(Feedback Subscriber):订阅动作服务器反馈的话题(Feedback Topic),实时获取任务进展。

    • 结果客户端(Result Service Client):请求任务完成后的结果。

  • 动作服务器(Action Server)

    • 目标服务端(Goal Service Server):接收来自客户端的目标请求,并决定是否接受执行该目标任务。

    • 反馈发布者(Feedback Publisher):在任务执行过程中不断地通过反馈话题发布实时进展。

    • 结果服务服务器(Result Service Server):任务完成后返回最终结果给客户端。

交互流程说明:

  1. 发送目标请求(Goal Request)

    • 动作客户端通过目标客户端,向动作服务器的目标服务端发送目标请求(例如机器人导航到某一位置)。
  2. 接收目标响应(Goal Response)

    • 动作服务器的目标服务端接收到请求后决定是否接受这个目标,并发送响应给动作客户端。

    • 如果服务器接受任务,就会开始执行;如果拒绝,客户端就会收到拒绝响应。

  3. 反馈(Feedback)通信

    • 任务执行过程中,动作服务器通过反馈发布者持续地通过反馈话题向动作客户端发布反馈信息,描述任务的进展情况(例如导航过程中实时位置更新)。
  4. 结果请求(Result Request)和响应(Result Response)

    • 当动作服务器完成任务时,结果服务端会通过服务返回最终的结果(例如导航任务完成后的最终位置)。

    • 动作客户端通过结果服务客户端请求并获取该结果。

通过这样的通信结构,ROS 2动作机制实现了长时间执行任务的启动、中途反馈、完成后结果返回甚至任务取消的完整闭环管理,适用于复杂的机器人应用场景,如导航、抓取、长时间计算任务等。

动作定义 Fibonacci(.action文件结构说明)

在ROS 2中,动作的定义通过扩展名为.action的文件描述,它定义了动作的目标(Goal)结果(Result)反馈(Feedback) 三个组成部分。以我们本章使用的 Fibonacci 动作为例:

Fibonacci.action:

# Goal(目标定义部分)
int32 order
---
# Result(结果定义部分)
int32[] sequence
---
# Feedback(反馈定义部分)
int32[] partial_sequence

该动作定义文件包含三部分,每个部分之间使用---分隔:

  • 目标(Goal)

    • orderint32类型):指定客户端发送的请求目标,即需要计算的斐波那契数列的元素个数。

    • 客户端向动作服务器发送的目标请求中包含此字段。

  • 结果(Result)

    • sequenceint32[]类型):表示最终返回给客户端的完整斐波那契数列结果。

    • 当动作服务器完成计算任务后,服务器将这个数组返回给客户端。

  • 反馈(Feedback)

    • partial_sequenceint32[]类型):表示任务进行过程中实时返回给客户端的部分数列,用于实时监控任务进展。

    • 动作服务器会定期通过反馈机制向客户端发送这个数组。

ROS2 动作常用命令与示例

ROS2 提供了一系列便捷的命令行工具,用于检查、调试和使用动作(Action)通信机制。本节将详细介绍这些常用命令及其具体的实例用法。同时,本节将以 ROS2 官方示例程序 turtlesim 为例,展示动作命令的实际使用场景。

1. 启动 turtlesim 示例节点

在使用动作命令之前,我们首先启动两个必要的节点:turtlesim_node(海龟仿真)和 turtle_teleop_key(键盘控制节点)。

(1). 启动 turtlesim_node(提供动作服务器):

打开第一个终端,运行:

ros2 run turtlesim turtlesim_node

此时,界面上会显示一个蓝色的海龟仿真窗口,模拟了海龟的运动场景。

(2). 启动 turtle_teleop_key(动作客户端):

打开第二个终端,运行:

ros2 run turtlesim turtle_teleop_key

启动后终端中将显示:

使用箭头键移动海龟。 使用G|B|V|C|D|E|R|T键旋转到绝对方向。按'F'键取消旋转。

  • 使用箭头键移动是通过话题(cmd_vel)控制海龟运动。

  • 使用G|B|V|C|D|E|R|T是通过动作(rotate_absolute)控制海龟旋转到特定的绝对方向。

此时系统中已启动了一个动作客户端(turtle_teleop_key)和一个动作服务器(turtlesim_node),接下来我们进行下一步动作相关命令的学习。

2. 查看系统内活跃的动作列表

使用如下命令查看当前ROS 2系统中激活的动作:

ros2 action list

示例输出:

/turtle1/rotate_absolute

说明turtlesim启动后,当前系统存在一个名为/turtle1/rotate_absolute的动作,用于控制海龟旋转。

3. 查看特定动作的详细信息

查看动作的客户端与服务器信息:

ros2 action info /turtle1/rotate_absolute

示例输出:

Action: /turtle1/rotate_absolute Action clients: 1 /teleop_turtle Action servers: 1 /turtlesim

  • 客户端节点为teleop_turtle(键盘输入端)。

  • 服务器节点为turtlesim(仿真节点,执行旋转操作)。

4. 查看动作类型的定义结构

查看动作的目标(Goal)、反馈(Feedback)和结果(Result)结构:

ros2 interface show turtlesim/action/RotateAbsolute

示例输出:

float32 theta 
---
float32 delta
---
float32 remaining
  • theta:目标方向(绝对角度,以弧度表示)。

  • delta:动作完成后的实际旋转角度。

  • remaining:反馈当前距离目标的剩余角度。

5. 从命令行发送动作目标

发送动作目标给turtlesim,使其旋转到绝对角度(例如90度,即约1.57弧度):

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.57}"

示例输出:

Waiting for an action server to become available... Sending goal: theta: 1.57 Goal accepted with ID: xxxxxxx
Result: delta: -1.568000078201294 Goal finished with status: SUCCEEDED`

6. 接收动作反馈信息

使用--feedback选项实时接收反馈信息:

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: -1.57}" --feedback

示例输出:

Sending goal:
theta: -1.57

Goal accepted with ID: xxxxxxx

Feedback:
remaining: -3.12

Feedback:
remaining: -2.98

Feedback:
remaining: -1.56

...

Result:
delta: 3.140000104904175

Goal finished with status: SUCCEEDED

在执行旋转动作的过程中,终端不断更新剩余角度,直到达到目标位置。

7. 动作目标的取消与中止操作示例

动作的一大优势是可以中途取消(客户端)或者中止(服务器端):

客户端主动取消动作目标:

在客户端通过键盘输入动作目标后,可以通过F键取消当前的旋转动作目标。

  • 在第二个终端(键盘控制)中,先按下C键开始旋转。
  • 在旋转完成前,按下F键取消目标。
turtlesim_node 终端输出:
[INFO] [turtlesim]: 旋转目标已取消

8. 服务器端中止动作目标:

服务器端可以主动中止旧的目标,比如新目标抵达时:

  • 先按下D键,旋转尚未完成前,再按下G键发送新的旋转目标。

此时服务器端终端显示:

[WARN] [turtlesim]: 在先前的目标完成之前收到了旋转目标。中止先前的目标。

服务器节点主动中止旧的目标,执行新的目标。